package com.hongdee.crm.tdc.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hongdee.common.util.DateUtils;
import com.hongdee.common.util.StringUtil;
import com.hongdee.common.util.TokenUtil;
import com.hongdee.crm.tdc.mapper.MarketQuestionMapper;
import com.hongdee.crm.tdc.mapper.MarketQuestionOrderMapper;
import com.hongdee.crm.tdc.pojo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhangkai
 * @desc 一句话描述
 **/
@Service
public class MarketQuestionServiceImpl implements IMarketQuestionService {

    @Autowired
    MarketQuestionMapper questionMapper;
    @Autowired
    MarketQuestionOrderMapper orderMapper;

    /**
     * 分页查询记录
     *
     * @param page
     * @param limit
     * @param pid
     * @return
     * @throws Exception
     */
    @Override
    public PageInfo<MarketQuestionLibraryPojo> page(int page, int limit, String pid, String brand) throws Exception {
        PageHelper.startPage(page, limit);
        List<MarketQuestionLibraryPojo> ls = questionMapper.queryLibrary(pid, brand, false, "");
        PageInfo<MarketQuestionLibraryPojo> info = new PageInfo<>(ls);
        return info;
    }

    /***
     * 新增记录
     * @param po
     * @throws Exception
     */
    @Override
    public void saveOrUpdateLibary(MarketQuestionLibraryPojo po) throws Exception {

        if (po.getpId() == null) {
            po.setpId("");
        }

        // 在同一目录下，判断是否存在相同名称的问题项，如查有则不通过，不存在则通过
        List<MarketQuestionLibraryPojo> ls = questionMapper.existsLibraryStatus(po.getLabel(), po.getpId(), po.getId());
        if (ls.size() > 0) {
            throw new Exception("已存在相同的平级标签");
        }
        //新增的时候，赋值ID
        if (po.getId() == null || po.getId().length() == 0) {
            po.setId(StringUtil.UUID());
            po.setStatus("1");
            questionMapper.addLibrary(po);
        } else {
            questionMapper.updateLibrary(po);
        }
    }


    /**
     * 更新状态
     *
     * @param id
     * @param status
     * @throws Exception
     */
    @Override
    public void updateLibaryStatus(String id, String status) throws Exception {
        questionMapper.updateLibraryStatus(id, status);
    }

    /***
     * 查询问题树
     * 仅查询 问题分类与问题项
     * @return
     * @throws Exception
     */
    @Override
    public List<MarketQuestionLibraryPojo> treeLibaray(String pid) throws Exception {
        List<MarketQuestionLibraryPojo> ls = questionMapper.queryLibrary(pid, null, true, "");
        return ls;
    }

    /**
     * 查询详情
     *
     * @param id
     * @return
     */
    @Override
    public MarketQuestionLibraryPojo info(String id) throws Exception {
        return questionMapper.queryLibraryInfoSQL(id);
    }

    /**
     * 分页查询记录
     *
     * @param page
     * @param limit
     * @param code
     * @return
     * @throws Exception
     */
    @Override
    public PageInfo<MarketNairePoJo> pageNaire(int page, int limit, String companyId, String code) throws Exception {
        PageHelper.startPage(page, limit);
        List<MarketNairePoJo> ls = questionMapper.queryNaire(companyId, code);
        PageInfo<MarketNairePoJo> info = new PageInfo<>(ls);
        return info;
    }

    /***
     * 新增记录
     * @param uid
     * @param reqVo {info:MarketnairePoJo items:[]}
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public MarketNairePoJo saveOrUpdateNarie(String uid, RequestPo reqVo) throws Exception {
        /****
         * 判断是否存在
         */
        String companyId = TokenUtil.getCompanyId(uid);
        MarketNairePoJo po = reqVo.getInfo();
        if (!StringUtils.isEmpty(po.getId())) {
            // 更新
            po.setCompanyId(companyId);
            po.setUpdateTime(DateUtils.getTimeStr());
            po.setUpdateUser(uid);
            questionMapper.updateNaire(po);
        } else {
            po.setCompanyId(companyId);
            po.setCreateTime(DateUtils.getTimeStr());
            po.setCreateUser(uid);
            po.setStatus("0");
            po.setId(StringUtil.UUID());
            questionMapper.addNaire(po);
        }
        // 调研问卷编码
        String naaireNum = po.getCode();
        List<MarketQuestionLibraryPojo> items = reqVo.getItems();

        MarketQuestionnairePojo nariePo;

        Map<String, String> existNodeMap = new HashMap();
        // 删除已有的记录
        questionMapper.deleteNaireItem(naaireNum);
        for (MarketQuestionLibraryPojo libPo : items) {
            //如果已存在，继续下一条
            if (existNodeMap.containsKey(libPo.getId())) {
                continue;
            }
            existNodeMap.put(libPo.getId(), libPo.getId());

            nariePo = new MarketQuestionnairePojo();
            nariePo.setCompanyId(companyId);
            nariePo.setNarieCode(naaireNum);
            nariePo.setMarketQuestionLibraryPojo(libPo);
            nariePo.setId(StringUtil.UUID());
            nariePo.setAssginScore(0);
            questionMapper.addNaireInfo(nariePo);
            /****
             * 由于ElementTree的特性，无法选中所有节点 需要对节点进行处理
             */
            // 判断当前节点类型
            if ("问题分类".equals(nariePo.getLabelType())) {
                //无上级节点，下一条
                continue;
            }
            if ("问题项".equals(nariePo.getLabelType())) {

                if (existNodeMap.containsKey(nariePo.getpId())) {
                    // 上级节点-问题分类已添加，继续下一条，
                    continue;
                }

                libPo = questionMapper.queryLibraryInfoSQL(nariePo.getpId());
                existNodeMap.put(libPo.getId(), libPo.getId());
                nariePo = new MarketQuestionnairePojo();
                nariePo.setCompanyId(companyId);
                nariePo.setNarieCode(naaireNum);
                nariePo.setMarketQuestionLibraryPojo(libPo);
                nariePo.setId(StringUtil.UUID());
                questionMapper.addNaireInfo(nariePo);
                continue;
            }

            if ("评分项".equals(nariePo.getLabelType())) {

                if (existNodeMap.containsKey(nariePo.getpId())) {
                    // 上级节点-问题项已添加，继续下一条，
                    continue;
                }
                //问题项
                libPo = questionMapper.queryLibraryInfoSQL(nariePo.getpId());
                existNodeMap.put(libPo.getId(), libPo.getId());
                nariePo = new MarketQuestionnairePojo();
                nariePo.setCompanyId(companyId);
                nariePo.setNarieCode(naaireNum);
                nariePo.setMarketQuestionLibraryPojo(libPo);
                nariePo.setId(StringUtil.UUID());
                questionMapper.addNaireInfo(nariePo);

                // 问题分类
                if (existNodeMap.containsKey(nariePo.getpId())) {
                    // 上级节点-问题项已添加，继续下一条，
                    continue;
                }
                //问题分类
                libPo = questionMapper.queryLibraryInfoSQL(nariePo.getpId());
                existNodeMap.put(libPo.getId(), libPo.getId());
                nariePo = new MarketQuestionnairePojo();
                nariePo.setCompanyId(companyId);
                nariePo.setNarieCode(naaireNum);
                nariePo.setMarketQuestionLibraryPojo(libPo);
                nariePo.setId(StringUtil.UUID());
                questionMapper.addNaireInfo(nariePo);
                continue;
            }

        }
        return po;
    }


    /**
     * 更新状态
     *
     * @param id
     * @param status
     * @throws Exception
     */
    @Override
    public void updateNarireStatus(String id, String status) throws Exception {

        if ("1".equals(status)) {
            MarketNairePoJo nirePo = questionMapper.queryNaireInfo(id);
            questionMapper.countItemScore(nirePo.getCompanyId(), nirePo.getCode());
            questionMapper.countItemGroupScore(nirePo.getCompanyId(), nirePo.getCode());
            MarketNaireScorePoJo scorePo = questionMapper.queryNarieTotalScore(nirePo.getCode(), nirePo.getCompanyId());
            int countScore = scorePo.getScore();
            int nireScore = nirePo.getTotalScore();

            if (countScore != nireScore) {
                throw new Exception("经校验，试券实际分值与期望分值不符，请重设分值！");
            }
        }

        questionMapper.updateNaireStatus(id, status);
    }

    /**
     * 查询详情
     *
     * @param id
     * @return
     */
    @Override
    public MarketNairePoJo infonarire(String id) throws Exception {
        return questionMapper.queryNaireInfo(id);
    }

    /****
     * 查询问题树
     * @return
     */
    @Override
    public List<MarketQuestionLibraryPojo> fullTreeLibaray() throws Exception {
        List<MarketQuestionLibraryPojo> list = questionMapper.queryLibrary("", null, false, "1");
        return buildTreeParent(list);
    }


    /***
     * 拼接父节点
     * @param list
     * @return
     * @throws Exception
     */
    private List<MarketQuestionLibraryPojo> buildTreeParent(List<MarketQuestionLibraryPojo> list) throws Exception {
        if (list.size() == 0) {
            return list;
        }

        for (MarketQuestionLibraryPojo po : list) {
            String pId = po.getId();
            List<MarketQuestionLibraryPojo> childList = buildTreeChild(pId);
            po.setChild(childList);
        }
        return list;
    }

    /***
     * 拼接子节点
     * @param pId
     * @return
     * @throws Exception
     */
    private List<MarketQuestionLibraryPojo> buildTreeChild(String pId) throws Exception {
        List<MarketQuestionLibraryPojo> list = questionMapper.queryLibrary(pId, null, false, "1");
        return buildTreeParent(list);
    }

    /***
     * 查询问券内容详细
     * @param narieCode
     * @param loadItem
     * @return
     */
    @Override
    public List<MarketQuestionnairePojo> fullTreeNarie(String narieCode, String companyId, Boolean loadItem) throws Exception {
        List<MarketQuestionnairePojo> list = questionMapper.queryNaireItem("", narieCode, companyId);
        return buildTreeNarieParent(list, loadItem);
    }

    /***
     * 分页查询问券详细
     * @param page
     * @param limit
     * @param companyId
     * @param code
     * @param pId
     * @return
     */
    @Override
    public PageInfo pageNaireItem(int page, int limit, String companyId, String code, String pId) {
        PageHelper.startPage(page, limit);
        List<MarketQuestionnairePojo> ls = questionMapper.queryNaireItem(pId, code, companyId);
        PageInfo<MarketQuestionnairePojo> info = new PageInfo<>(ls);
        return info;
    }

    /**
     * 更新分值
     *
     * @param id
     * @param score
     */
    @Override
    public void updateNarireItemScore(String id, int score) throws Exception {
        questionMapper.updateNaireInfoScore(id, score);
    }

    /***
     * 校验分值
     * @param code
     * @return
     * @throws Exception
     */
    @Override
    public Integer checkScore(String code, String companyId) throws Exception {
        /****
         * 校验总分
         * 1.直接取总分值
         */
        questionMapper.countItemScore(companyId, code);
        questionMapper.countItemGroupScore(companyId, code);
        MarketNaireScorePoJo scorePo = questionMapper.queryNarieTotalScore(code, companyId);
        Integer countScore = scorePo.getScore();

        return countScore;
    }

    /***
     * 加载研问券
     * @param orderNum
     * @param companyId
     * @return
     */
    @Override
    public Integer loadQuestionOrder(String orderNum, String companyId) throws Exception {

        /**
         * 判断是否有调研问券,如果有则返回
         *
         * */
        MarketNairePoJo numLs = orderMapper.queryOrderNum(companyId, orderNum);
        if (numLs.getTotalScore() > 1) {
            return 1;
        }

        /***
         * 如果没有，则加载调研问券
         */
        //设定参数
        MarketNairePoJo po = orderMapper.queryParam(companyId);
        if (StringUtils.isEmpty(po.getCode()) || po.getCode().length() < 10) {
            throw new Exception("请先配置系统参数-调研问券启用此功能！");
        }
        //启用问券
        MarketNairePoJo nairePoJo = orderMapper.queryQusetionOrder(companyId, po.getCode());
        if (!"1".equals(nairePoJo.getStatus())) {
            throw new Exception("调研问券「" + po.getCode() + "」未起用，请先启用");
        }
        // 绑定工单
        orderMapper.bindOrderNumAndNarieNo(orderNum, po.getCode(), companyId);
        return 1;
    }


    /***
     * 拼接父节点
     * @param list
     * @return
     * @throws Exception
     */
    private List<MarketQuestionnairePojo> buildTreeNarieParent(List<MarketQuestionnairePojo> list, Boolean loadItem) throws Exception {
        if (list.size() == 0) {
            return list;
        }

        for (MarketQuestionnairePojo po : list) {
            String pId = po.getLibraryId();
            String narieCode = po.getNarieCode();
            String companyId = po.getCompanyId();
            String type = po.getLabelType();


            if (loadItem) {
                List<MarketQuestionnairePojo> childList = buildTreeNarieChild(pId, narieCode, companyId, loadItem);
                po.setChild(childList);
            } else {
                String labelType = po.getLabelType().equals("1") ? "(填空)" : "(选择)";
                if ("问题项".equals(type)) {
                    po.setLabel(po.getLabel() + labelType);
                }

                if ("问题项".equals(type) || "评分项".equals(type)) {
                    List<MarketQuestionnairePojo> childList = buildTreeNarieParent(new ArrayList<MarketQuestionnairePojo>(), loadItem);
                    po.setChild(childList);
                } else {
                    List<MarketQuestionnairePojo> childList = buildTreeNarieChild(pId, narieCode, companyId, loadItem);
                    po.setChild(childList);
                }
            }


        }
        return list;
    }

    /***
     * 拼接子节点
     * @param pId
     * @return
     * @throws Exception
     */
    private List<MarketQuestionnairePojo> buildTreeNarieChild(String pId, String narieCode, String companyId, boolean loadItem) throws Exception {
        List<MarketQuestionnairePojo> list = questionMapper.queryNaireItem(pId, narieCode, companyId);
        return buildTreeNarieParent(list, loadItem);
    }


    /***
     * 加载工单绑定后的问券树
     * @param orderNum
     * @param companyId
     * @return
     */
    @Override
    public List<MarketTdcQuestionScorePojo> loadQuestionOrderTree(String orderNum, String companyId) throws Exception {
        List<MarketTdcQuestionScorePojo> list = orderMapper.queryQuestionItem("", orderNum, companyId);
        return buildTreeOrderParent(list);
    }

    /***
     * 任务处理-回答问题得分
     * @param id
     * @param score
     * @throws Exception
     */
    @Override
    public void updateOrderScore(String id, int score) throws Exception {
        orderMapper.updateOrderScore(id, score);
        Map map = orderMapper.countParentScore(id);
        orderMapper.updateOrderScoreByOrderNum(String.valueOf(map.get("p_id")), Integer.parseInt(map.get("score").toString()),
                String.valueOf(map.get("order_num")),
            String.valueOf(map.get("company_id"))
        );
    }

    /**
     * 拼写工单对应的问券父节点
     *
     * @param list
     * @return
     * @throws Exception
     */
    private List<MarketTdcQuestionScorePojo> buildTreeOrderParent(List<MarketTdcQuestionScorePojo> list) throws Exception {
        if (list.size() == 0) {
            return list;
        }

        for (MarketTdcQuestionScorePojo po : list) {
            String pId = po.getLibraryId();


            List<MarketTdcQuestionScorePojo> childList = buildTreeOrderChild(pId, po.getOrderNum(), po.getCompanyId());
            po.setChildren(childList);


        }
        return list;
    }

    /***
     * 拼写工单对应的问券子节点
     * @param pId
     * @param orderNum
     * @param companyId
     * @return
     * @throws Exception
     */
    private List<MarketTdcQuestionScorePojo> buildTreeOrderChild(String pId, String orderNum, String companyId) throws Exception {
        List<MarketTdcQuestionScorePojo> list = orderMapper.queryQuestionItem(pId, orderNum, companyId);
        return buildTreeOrderParent(list);
    }
}
